package repository

import (
	"fmt"
	gamedb "game/game-db"
	"game/game-db/orm"
	"strings"
)

type IRepository[T orm.IDbEntity] interface {
	GetByKeys(keys ...interface{}) (T, bool) //通过关系keys获取一条数据
	ListByKeys(keys ...interface{}) []T      //通过关系keys获取一组数据
	Insert(entity T) error                   //插入数据
	InsertAll(entities []T)                  //插入批量数量
	Update(entity T)                         //更新数据
	UpdateAll(entities []T)                  //更新批量数据
	Delete(entity T)                         //删除数据
	DeleteAll(entities []T)                  //删除批量数据
	Scan()                                   //查看仓库中数据的情况
	LoadAll() []T                            //从仓库中加载所有数据
}

func getListFromDb[T orm.IDbEntity](dao gamedb.IDao[T], keyOptions *keyOptions) []T {
	if keyOptions == nil || keyOptions.IsEmpty() {
		return dao.All()
	}
	var where strings.Builder
	where.WriteString("WHERE ")

	queryParams := make([]interface{}, 0)
	for i, option := range keyOptions.options {
		columnName := dao.EntityMeta().ColumnNameByFieldName(option.fieldName)
		if columnName == "" {
			panic("can not find columnName with fieldName : " + option.fieldName)
		}
		if i != 0 {
			where.WriteString(" AND ")
		}
		where.WriteString(columnName)
		where.WriteString("=?")
		queryParams = append(queryParams, option.value)
	}
	fmt.Println("getListFromDb", where.String())
	return dao.QueryWhere(where.String(), queryParams...)
}

func getOneFromDb[T orm.IDbEntity](dao gamedb.IDao[T], keyOptions *keyOptions) (T, bool) {
	ts := getListFromDb(dao, keyOptions)
	if len(ts) > 1 {
		panic(fmt.Sprint("result set for key options ", keyOptions, " more than one"))
	} else if len(ts) == 1 {
		return ts[0], true
	} else {
		var entity T
		return entity, false
	}
}
